package com.zx.idc.backend.gui.api.management.basicdata.query.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zx.idc.backend.gui.api.commom.entity.CommandModel;
import com.zx.idc.backend.gui.api.commom.entity.UploadModel;
import com.zx.idc.backend.gui.api.commom.template.NIdcFtpTemplate;
import com.zx.idc.backend.gui.api.management.basicdata.BaseIdcBasicDataService;
import com.zx.idc.backend.gui.api.management.basicdata.common.BasicDataDefaultInstance;
import com.zx.idc.backend.gui.api.management.basicdata.common.MonitorService;
import com.zx.idc.backend.gui.api.management.basicdata.query.IdcBasicDataQueryService;
import com.zx.idc.backend.gui.api.management.basicdata.report.IdcBasicDataUtil;
import com.zx.idc.common.attributes.FTPReportDataTypeEnum;
import com.zx.idc.common.attributes.NetCommunicationFileTypeEnum;
import com.zx.idc.common.attributes.SchemaFileNameEnum;
import com.zx.idc.common.attributes.SystemAttributes;
import com.zx.idc.common.lang.ListUtil;
import com.zx.idc.ds.base.cus.entity.BaseCustomer;
import com.zx.idc.ds.base.cus.service.IBaseCustomerService;
import com.zx.idc.ds.base.cus.service.IBaseServiceInfoService;
import com.zx.idc.ds.base.house.entity.*;
import com.zx.idc.ds.base.house.service.*;
import com.zx.idc.ds.base.house.vo.BaseHousesHoldInfoVo;
import com.zx.idc.ds.base.ip.entity.BaseIpAddressInfo;
import com.zx.idc.ds.base.ip.service.IBaseIpAddressInfoService;
import com.zx.idc.ds.base.oper.entity.BaseOperCompany;
import com.zx.idc.ds.base.oper.service.IBaseOperCompanyService;
import com.zx.idc.ds.base.serve.entity.BaseServiceDomain;
import com.zx.idc.ds.base.serve.service.IBaseServiceDomainService;
import com.zx.idc.ds.base.server.service.IBaseServerInfoService;
import com.zx.idc.ds.common.constant.ReportStatusConstant;
import com.zx.idc.ds.ins.entity.InsAdminControl;
import com.zx.idc.ds.ins.service.IInsAdminControlService;
import com.zx.idc.ds.slog.entity.SlogHotIp;
import com.zx.idc.ds.slog.service.ISlogAbnormalIpService;
import com.zx.idc.ds.slog.service.ISlogHotIpService;
import com.zx.idc.ds.slog.vo.SlogAbnormalIpVo;
import com.zx.idc.xml.entity.basedata.BasicInfo;
import com.zx.idc.xml.entity.basedata.QueryResult;
import com.zx.idc.xml.entity.basedata.basic.EmergencyContact;
import com.zx.idc.xml.entity.basedata.basic.HouseInfo;
import com.zx.idc.xml.entity.basedata.basic.IdcOfficer;
import com.zx.idc.xml.entity.basedata.basic.UserInfo;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.FrameInfo;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.GatewayInfo;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.HouseOfficer;
import com.zx.idc.xml.entity.basedata.basic.houseinfo.IpSegInfo;
import com.zx.idc.xml.entity.basedata.basic.userinfo.*;
import com.zx.idc.xml.entity.idcinfomanage.IdcInfoManage;
import com.zx.idc.xml.entity.idcinfomanage.commandinfo.CommandInfo;
import com.zx.idc.xml.entity.idcmonitor.IdcMonitor;
import com.zx.idc.xml.entity.idcmonitor.housemonitor.HouseMonitor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.zx.idc.common.constants.IdcInfoManageTypeConstants.QUERY_BASIC_DATA_MONITORING_EXCEPTION;
import static com.zx.idc.common.constants.IdcInfoManageTypeConstants.QUERY_BASIC_DATA_RECORDS;

/**
 * @author rxliuli
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class IdcBasicDataQueryServiceImpl implements IdcBasicDataQueryService {
    private static final Logger LOG = LoggerFactory.getLogger(IdcBasicDataQueryServiceImpl.class);

    /**
     * 不查询的标识
     */
    private static final long NON_QUERY = -1;
    private static final String COLUMN_FIND_IP_LIST_FIRST_TIME = "findIpListFirstTime";
    private static final String COLUMN_FIND_IP_LIST_LAST_TIME = "findIpListLastTime";
    private static final String COLUMN_HOUSE_ID = "houseId";
    private static final String COLUMN_ID = "Id";
    private static final String COLUMN_HOUSE_AREA = "houseArea";
    private static final Integer TYPE_OTHER_USER = 2;
    private static final Integer TYPE_INTERNET_USER = 1;
    private static final String COMMA_SEPARATED = ",";
    private static final String COLUMN_FRAME_INFO_ID = "frameInfoId";

    @Autowired
    private IBaseOperCompanyService baseOperCompanyService;
    @Autowired
    private IBaseHouseInfoService baseHouseInfoService;
    @Autowired
    private IBaseCustomerService baseCustomerService;
    @Autowired
    private IBaseHouseOfficerService baseHouseOfficerService;
    @Autowired
    private IBaseHouseLinkInfoService baseHouseLinkInfoService;
    @Autowired
    private IBaseIpAddressInfoService baseIpAddressInfoService;
    @Autowired
    private IBaseIdcHouseAreaService baseIdcHouseAreaService;
    @Autowired
    private IBaseFrameInfoService baseFrameInfoService;
    @Autowired
    private IBaseHousesHoldInfoService baseHousesHoldInfoService;
    @Autowired
    private IBaseIpTransInfoService baseIpTransInfoService;
    @Autowired
    private IBaseServiceDomainService baseServiceDomainService;
    @Autowired
    private NIdcFtpTemplate nIdcFtpTemplate;
    @Autowired
    private IBaseServiceInfoService baseServiceInfoService;
    @Autowired
    private BasicDataDefaultInstance basicDataDefaultInstance;
    @Autowired
    private MonitorService monitorService;
    @Autowired
    private IInsAdminControlService iInsAdminControlService;

    @Override
    public void commandQuery(IdcInfoManage idcInfoManage, CommandModel commandModel) {
        /*
        - 基础数据查询上报信息 `QueryResult -> BaseOperCompany`
          - 人员信息 `PersonnelInfo -> BaseHouseOfficer`
          - 机房数据 `HouseInfo -> BaseHouseInfo`
            - 人员信息 `PersonnelInfo -> BaseHouseOfficer`
            - 链路信息 `GeteWayInfo -> BaseHouseLinkInfo`
            - ip 地址段信息 `IpSegInfo -> BaseIpAddressInfo`
            - 机架信息 `FrameInfo -> BaseFrameInfo`
          - 用户数据 `UserInfo -> BaseCustomer`
            - 提供互联网应用服务的用户信息 `Info -> BaseCustomer`
              - 人员信息 `PersonnelInfo -> BaseHouseOfficer`
              - 服务信息 `ServiceInfo -> BaseServiceInfo`
              - 占用机房信息 `HouseHoldInfo -> BaseHousesHoldInfo`
                - 虚拟主机信息 `VirtualServer -> BaseHousesHoldInfo`
                - ip 地址转换信息 `IpTrans -> BaseIpTransInfo`
            - 其他用户信息 `OtherUserInfo -> BaseCustomer`
              - 占用机房信息 `HouseHoldInfo -> BaseHousesHoldInfo`
         */
        //记录管控指令
        InsAdminControl insAdminControl = new InsAdminControl()
            .setInsType(SystemAttributes.INS_TYPE_DATABASE_SELECT)
            .setIdcId(commandModel.getIdcId())
            .setCreateTime(idcInfoManage.getTimestamp())
            .setCommandId(String.valueOf(idcInfoManage.getCommandId()))
            .setReportStatus(ReportStatusConstant.NOT_REPORTED)
            .setInsContents(JSON.toJSONString(idcInfoManage));
        iInsAdminControlService.insert(insAdminControl);
        Integer type = idcInfoManage.getType();
        if (QUERY_BASIC_DATA_RECORDS.equals(type)) {
            uploadQueryBaseData(idcInfoManage);
        } else if (QUERY_BASIC_DATA_MONITORING_EXCEPTION.equals(type)) {
            uploadQueryAbnormalBaseData(idcInfoManage);
        }
        LOG.info("基础数据查询上报信息执行成功");
    }

    /**
     * 基础数据异常查询指令
     *
     * @param idcInfoManage
     * @return
     */
    public void uploadQueryAbnormalBaseData(IdcInfoManage idcInfoManage) {
        try {
            CommandInfo commandInfo = idcInfoManage.getCommandInfo();
            String idcId = commandInfo.getIdcId();
            if (StringUtils.isEmpty(idcId)) {
                LOG.error("基础数据异常数据查询失败，IdcId为空，基础数据异常查询指令结束。");
                return;
            }
            List<BaseHouseInfo> baseHouseInfos = baseHouseInfoService.selectList(new BaseHouseInfo().setIdcId(idcId));
            if (ListUtil.isEmpty(baseHouseInfos)) {
                LOG.error("基础数据异常数据查询失败，IdcId不存在或者Idc不存在机房，基础数据异常查询指令结束。");
                return;
            }

            EntityWrapper<SlogHotIp> entityWrapper = new EntityWrapper<>();
            if (commandInfo.getQueryMonitorDayTo() != null && commandInfo.getQueryMonitorDayFrom() != null) {
                entityWrapper.ge(COLUMN_FIND_IP_LIST_FIRST_TIME, commandInfo.getQueryMonitorDayFrom())
                    .le(COLUMN_FIND_IP_LIST_LAST_TIME, commandInfo.getQueryMonitorDayTo());
            }

            List<HouseMonitor> houseMonitors = new ArrayList<>();
            for (BaseHouseInfo baseHouseInfo : baseHouseInfos) {
                List<HouseMonitor> houseMonitorSubList = monitorService.queryBaseAbnormalData(baseHouseInfo.getId());
                if (houseMonitorSubList.size() == 0) {
                    HouseMonitor houseMonitor = monitorService.getZeroReportData(baseHouseInfo.getId());
                    houseMonitors.add(houseMonitor);
                }else{
                    houseMonitors.addAll(houseMonitorSubList);
                }
            }

            IdcMonitor idcMonitor = new IdcMonitor()
                .setCommandId(idcInfoManage.getCommandId())
                .setTimeStamp(LocalDateTime.now())
                .setIdcId(idcId)
                .setHouseMonitor(houseMonitors);

            nIdcFtpTemplate.uploadXMLFile(
                new UploadModel<>(
                    idcMonitor,
                    SchemaFileNameEnum.BASE_DATA_EXCEPTION_DATA_REPORT,
                    FTPReportDataTypeEnum.FTP_BASE_DATA_MONITORING_ABNORMAL_RECORDS,
                    NetCommunicationFileTypeEnum.INSTRUCTION_QUERY
                )
            );
        } catch (Exception e) {
            LOG.error("基础数据异常数据查询指令异常", e);
            throw new RuntimeException(e);
        }

    }

    /**
     * 手动上传异常ip到管局
     *
     * @param abnormalIpList
     * @return
     */
    public void uploadAbnormalIpForManual(List<SlogAbnormalIpVo> abnormalIpList) {
        try {
            //把上报记录用hostId分组
            Map<Long, List<SlogAbnormalIpVo>> abnormalIpMap = new HashMap<>();
            abnormalIpList.stream().forEach(abnormalIpVo -> {
                if(abnormalIpMap.get(abnormalIpVo.getHouseId())==null){
                    List<SlogAbnormalIpVo> subList = new ArrayList<>();
                    abnormalIpMap.put(abnormalIpVo.getHouseId(), subList);
                }
                abnormalIpMap.get(abnormalIpVo.getHouseId()).add(abnormalIpVo);
            });

            List<HouseMonitor> houseMonitors = new ArrayList<>();
            for (Map.Entry<Long, List<SlogAbnormalIpVo>> entry : abnormalIpMap.entrySet()) {
                List<HouseMonitor> houseMonitorSubList = monitorService.wrapperAbnormalIpUploadData(entry.getValue());
                houseMonitors.addAll(houseMonitorSubList);
            }

            Long houseId = abnormalIpList.get(0).getHouseId();
            BaseHouseInfo baseHouseInfo = baseHouseInfoService.selectById(houseId);
            IdcMonitor idcMonitor = new IdcMonitor()
                .setCommandId(null)
                .setTimeStamp(LocalDateTime.now())
                .setIdcId(baseHouseInfo.getIdcId())
                .setHouseMonitor(houseMonitors);

            nIdcFtpTemplate.uploadXMLFile(
                new UploadModel<>(
                    idcMonitor,
                    SchemaFileNameEnum.BASE_DATA_EXCEPTION_DATA_REPORT,
                    FTPReportDataTypeEnum.FTP_BASE_DATA_MONITORING_ABNORMAL_RECORDS,
                    NetCommunicationFileTypeEnum.INSTRUCTION_QUERY
                )
            );
        } catch (Exception e) {
            LOG.error("基础数据异常数据查询指令异常", e);
            throw new RuntimeException(e);
        }

    }


    /**
     * 上报基础数据查询
     *
     * @param idcInfoManage
     */
    private void uploadQueryBaseData(IdcInfoManage idcInfoManage) {
        try {
            CommandInfo commandInfo = idcInfoManage.getCommandInfo();
            //经营者信息
            final BaseOperCompany baseOperCompany = baseOperCompanyService.selectById(commandInfo.getIdcId());
            final BasicInfo basicInfo = basicDataDefaultInstance.getBasicInfo();
            if (baseOperCompany == null) {
                LOG.error("基础数据查询指令IdcId不能为空或者经营单位不存在!");
                return;
            }
            QueryResult queryResult = defaultQueryResult(idcInfoManage, baseOperCompany);
            //机房信息
            queryResult.setHouseInfo(houseInfos(idcInfoManage))
                //用户信息
                .setUserInfo(userInfos(idcInfoManage));
            basicInfo.setQueryResult(queryResult);

            //TODO 未完成待确定
            nIdcFtpTemplate.uploadXMLFile(
                new UploadModel<>(
                    basicInfo,
                    SchemaFileNameEnum.BASE_DATA_REPORT,
                    FTPReportDataTypeEnum.FTP_BASE_DATA,
                    NetCommunicationFileTypeEnum.BASE_DATA
                )
            );
        } catch (Exception e) {
            LOG.error("基础数据查询异常", e);
            throw new RuntimeException(e);
        }

    }

    /**
     * 用户信息
     *
     * @param idcInfoManage
     * @return
     */
    private List<UserInfo> userInfos(IdcInfoManage idcInfoManage) {
        CommandInfo commandInfo = idcInfoManage.getCommandInfo();
        List<Long> baseCustomerIds = commandInfo.getId();
        String idcId = commandInfo.getIdcId();
        List<BaseCustomer> baseCustomers = null;
        if (ListUtil.isEmpty(baseCustomerIds) || baseCustomerIds.get(0).equals(NON_QUERY)) {
            //TODO 因接口文档YD_T 2405-2015中表16与表24对于-1情况的处理存在冲突，目前只能忽略-1的情况，为-1时查询所有客户
            //为空则查询IDC下的所有客户
            baseCustomers = baseCustomerService.selectListByIdcId(idcId);
        } else if (!baseCustomerIds.get(0).equals(NON_QUERY)) {
            //不为-1时就查询指令客户
            baseCustomers = baseCustomerService.selectBatchIds(baseCustomerIds);
        }
        if (ListUtil.isEmpty(baseCustomers)) {
            return null;
        }
        return baseCustomers.stream()
            .map(baseCustomer ->
                new UserInfo()
                    .setId(baseCustomer.getId())
                    //用户信息
                    .setInfo(info(baseCustomer))
                    .setNature(baseCustomer.getUserType())
            ).collect(Collectors.toList());
    }

    /**
     * 设置客户的用户信息
     *
     * @param baseCustomer
     * @return
     */
    private Info info(BaseCustomer baseCustomer) {
        Info info = new Info()
            .setUnitName(baseCustomer.getUnitName())
            .setUnitNature(baseCustomer.getUnitNature())
            .setIdType(baseCustomer.getIdType())
            .setIdNumber(baseCustomer.getIdNumber())
            .setOfficer(
                uploadOfficer(baseCustomer.getOfficer())
            )
            .setAdd(baseCustomer.getAddress())
            .setZipCode(baseCustomer.getZipCode())
            .setRegisterTime(baseCustomer.getRegisterTime());
        Integer userType = baseCustomer.getUserType();
        //相应的用户类型做相应的扩充
        if (TYPE_OTHER_USER.equals(userType)) {
            //其他用户
            otherUserExpansion(info, baseCustomer);
        } else if (TYPE_INTERNET_USER.equals(userType)) {
            //互联网用户
            internetUserExpansion(info, baseCustomer);
        }
        return info;
    }

    private void internetUserExpansion(Info info, BaseCustomer baseCustomer) {
        info.setServiceInfo(
            //服务信息
            serviceInfo(baseCustomer)
        );
    }

    /**
     * 客户下的服务信息
     *
     * @param baseCustomer
     * @return
     */
    private List<ServiceInfo> serviceInfo(BaseCustomer baseCustomer) {
        List<BaseServiceInfo> baseServiceInfos = baseServiceInfoService.selectListByCustomerId(baseCustomer.getId());
        if (ListUtil.isEmpty(baseServiceInfos)) {
            return null;
        }
        return baseServiceInfos.stream()
            .map(baseServiceInfo ->
                new ServiceInfo()
                    .setServiceId(baseServiceInfo.getId())
                    .setServiceContent(
                        Arrays.stream(
                            baseServiceInfo.getServiceContent()
                                .split(COMMA_SEPARATED)
                        ).map(Integer::parseInt)
                            .collect(Collectors.toList())
                    )
                    .setRegType(baseServiceInfo.getRegType())
                    .setRegId(baseServiceInfo.getRegId())
                    .setSetMode(baseServiceInfo.getSetMode())
                    .setBusiness(baseServiceInfo.getBusinessType())
                    //设置域名信息
                    .setDomain(domain(baseServiceInfo))
                    //设置占用机房信息
                    .setHousesHoldInfo(housesHoldInfo(baseServiceInfo))
            ).collect(Collectors.toList());
    }

    /**
     * 互联网用户的占用机房信息
     *
     * @param baseServiceInfo
     * @return
     */
    private List<HousesHoldInfo> housesHoldInfo(BaseServiceInfo baseServiceInfo) {
        //查出机房下的分区下的机架信息
        List<BaseHousesHoldInfoVo> baseHousesHoldInfoVos = baseHousesHoldInfoService.selectVoListById(baseServiceInfo.getHoldId());
        return baseHousesHoldInfoVos.stream()
            .map(baseHousesHoldInfoVo ->
                new HousesHoldInfo()
                    .setHouseId(baseHousesHoldInfoVo.getHouseId())
                    .setHhId(baseHousesHoldInfoVo.getId())
                    .setBandWidth(baseHousesHoldInfoVo.getBandWidth())
                    .setDistributeTime(baseHousesHoldInfoVo.getDistributeTime())
                    .setFrameInfoId(baseHousesHoldInfoVo.getFrameInfoId())
                    .setVirtualServer(virtualServer(baseHousesHoldInfoVo))
                    .setIpTrans(ipTrans(baseHousesHoldInfoVo))
            ).collect(Collectors.toList());
    }

    private List<IpTrans> ipTrans(BaseHousesHoldInfoVo baseHousesHoldInfoVo) {
        return baseIpTransInfoService.selectListByHoldId(baseHousesHoldInfoVo.getId())
            .stream()
            .map(baseIpTransInfo ->
                new IpTrans()
                    .setInternetIp(internetIp(baseIpTransInfo))
                    .setNetIp(netIp(baseIpTransInfo))
            ).collect(Collectors.toList());
    }

    private NetIp netIp(BaseIpTransInfo baseIpTransInfo) {
        NetIp netIp = null;
        if (StringUtils.isNotEmpty(baseIpTransInfo.getPrivateStartIp())) {
            netIp = new NetIp()
                .setStartIp(baseIpTransInfo.getPrivateStartIp())
                .setEndIp(baseIpTransInfo.getPrivateEndIp());
        }
        return netIp;
    }

    private InternetIp internetIp(BaseIpTransInfo baseIpTransInfo) {
        return new InternetIp()
            .setStartIp(baseIpTransInfo.getInternetStartIp())
            .setEndIp(baseIpTransInfo.getInternetEndIp());
    }

    private VirtualServer virtualServer(BaseHousesHoldInfoVo baseHousesHoldInfoVo) {
        if (StringUtils.isNotEmpty(baseHousesHoldInfoVo.getVirtualHostName())) {
            return new VirtualServer()
                .setVirtualhostAddress(baseHousesHoldInfoVo.getVirtualHostAddress())
                .setVirtualhostManagementAddress(baseHousesHoldInfoVo.getVirtualHostManagement())
                .setVirtualhostName(baseHousesHoldInfoVo.getVirtualHostName())
                .setVirtualhostState(baseHousesHoldInfoVo.getVirtualHostState())
                .setVirtualhostType(baseHousesHoldInfoVo.getVirtualHostType());
        }
        return null;
    }

    /**
     * 域名信息
     *
     * @param baseServiceInfo
     * @return
     */
    private List<Domain> domain(BaseServiceInfo baseServiceInfo) {
        List<BaseServiceDomain> baseServiceDomains = baseServiceDomainService.selectList(
            new BaseServiceDomain().setServiceId(baseServiceInfo.getId())
        );
        if (ListUtil.isEmpty(baseServiceDomains)) {
            return null;
        }
        return baseServiceDomains.stream()
            .map(baseServiceDomain ->
                new Domain()
                    .setId(baseServiceDomain.getId())
                    .setName(baseServiceDomain.getDomain())
            )
            .collect(Collectors.toList());
    }

    /**
     * 用户类型为其他用户的扩充
     *
     * @param info
     * @param baseCustomer
     */
    private void otherUserExpansion(Info info, BaseCustomer baseCustomer) {
        info.setHouseHoldInfo(
            houseHoldInfo(baseCustomer)
        );
    }

    /**
     * 其他用户的占用机房信息
     *
     * @param baseCustomer
     * @return
     */
    private List<HouseHoldInfo> houseHoldInfo(BaseCustomer baseCustomer) {
        //查出机房下的分区下的机架信息
        List<BaseHousesHoldInfoVo> baseHousesHoldInfoVos = baseHousesHoldInfoService.selectVoListByCustomerId(baseCustomer.getId());
        return baseHousesHoldInfoVos.stream()
            .map(baseHousesHoldInfoVo ->
                new HouseHoldInfo()
                    .setHhId(baseHousesHoldInfoVo.getId())
                    .setHouseId(baseHousesHoldInfoVo.getHouseId())
                    .setDistributeTime(baseHousesHoldInfoVo.getDistributeTime())
                    .setBandWidth(baseHousesHoldInfoVo.getBandWidth())
                    .setIpSeg(ipSeg(baseHousesHoldInfoVo))
            ).collect(Collectors.toList());
    }

    /**
     * ip转换信息
     *
     * @param baseHousesHoldInfoVo
     * @return
     */
    private List<IpSeg> ipSeg(BaseHousesHoldInfoVo baseHousesHoldInfoVo) {
        return baseIpTransInfoService.selectListByHoldId(baseHousesHoldInfoVo.getId())
            .stream()
            .map(baseIpTransInfo ->
                new IpSeg()
                    .setStartIp(baseIpTransInfo.getInternetStartIp())
                    .setEndIp(baseIpTransInfo.getInternetEndIp())
                    .setIpId(baseIpTransInfo.getId())
            ).collect(Collectors.toList());
    }

    /**
     * 机房信息
     *
     * @return
     */
    private List<HouseInfo> houseInfos(IdcInfoManage idcInfoManage) {
        CommandInfo commandInfo = idcInfoManage.getCommandInfo();
        List<Long> queryHouseIds = commandInfo.getHouseId();
        List<HouseInfo> houseInfos = null;
        List<BaseHouseInfo> baseHouseInfos = null;
        if (ListUtil.isEmpty(queryHouseIds) || queryHouseIds.get(0).equals(NON_QUERY)) {
            //TODO 因接口文档YD_T 2405-2015中表16与表24对于-1情况的处理存在冲突，目前只能忽略-1的情况，为-1时查询所有机房
            //为空则查询IDC下的所有机房
            baseHouseInfos = baseHouseInfoService.selectListByIdcId(commandInfo.getIdcId());
        } else if (!queryHouseIds.get(0).equals(NON_QUERY)) {
            //不为-1时就查询指令机房
            baseHouseInfos = baseHouseInfoService.selectBatchIds(queryHouseIds);
        }

        if (ListUtil.isEmpty(baseHouseInfos)) {
            return null;
        }

        //查询机房关联的信息
        for (BaseHouseInfo baseHouseInfo : baseHouseInfos) {
            //机房信息
            HouseInfo houseInfo = uploadHouseInfo(baseHouseInfo)
                //链路信息
                .setGatewayInfo(uploadGatewayInfo(baseHouseInfo))
                //设置IP信息
                .setIpSegInfo(uploadIpSegInfo(baseHouseInfo))
                //设置负责人信息
                .setHouseOfficer(uploadHouseOfficer(baseHouseInfo.getHouseOfficer()))
                //机架信息
                .setFrameInfo(uploadFrameInfo(baseHouseInfo));

            houseInfos = new ArrayList<>(baseHouseInfos.size());
            houseInfos.add(houseInfo);
        }
        return houseInfos;
    }

    private List<BaseFrameInfo> frameInfo(Long houseId) {
        List<BaseIdcHouseArea> baseIdcHouseAreas = baseIdcHouseAreaService.selectList(
            new BaseIdcHouseArea().setHouseId(houseId)
        );
        if (ListUtil.isEmpty(baseIdcHouseAreas)) {
            return null;
        }
        List<Long> areas = baseIdcHouseAreas.stream()
            .filter(Objects::nonNull)
            .map(BaseIdcHouseArea::getId)
            .collect(Collectors.toList());

        return baseFrameInfoService.selectList(
            new EntityWrapper<BaseFrameInfo>()
                .in(COLUMN_HOUSE_AREA, areas)
        );
    }

    private List<FrameInfo> uploadFrameInfo(BaseHouseInfo baseHouseInfo) {
        //获取机房下的所有区域下的所有机架信息
        List<BaseFrameInfo> baseFrameInfos = frameInfo(baseHouseInfo.getId());
        if (ListUtil.isEmpty(baseFrameInfos)) {
            return null;
        }
        return baseFrameInfos.stream()
            .filter(Objects::nonNull)
            .map(baseFrameInfo ->
                new FrameInfo()
                    .setDistribution(baseFrameInfo.getDistribution())
                    .setFrameName(baseFrameInfo.getFrameName())
                    .setId(baseFrameInfo.getId())
                    .setUseType(baseFrameInfo.getUseType())
                    .setOccupancy(baseFrameInfo.getOccupancy())
            ).collect(Collectors.toList());
    }

    private HouseOfficer uploadHouseOfficer(Long houseOfficerId) {
        BaseHouseOfficer baseHouseOfficer = baseHouseOfficerService.selectById(
            houseOfficerId
        );
        return new HouseOfficer()
            .setEmail(baseHouseOfficer.getEmail())
            .setId(String.valueOf(baseHouseOfficer.getId()))
            .setIdType(baseHouseOfficer.getIdType())
            .setMobile(baseHouseOfficer.getMobile())
            .setName(baseHouseOfficer.getName())
            .setTel(baseHouseOfficer.getTel());
    }

    /**
     * 获取客户下的负责人信息
     *
     * @param houseOfficerId
     * @return
     */
    private Officer uploadOfficer(Long houseOfficerId) {
        BaseHouseOfficer baseHouseOfficer = baseHouseOfficerService.selectById(
            houseOfficerId
        );
        return new Officer()
            .setEmail(baseHouseOfficer.getEmail())
            .setId(String.valueOf(baseHouseOfficer.getId()))
            .setIdType(baseHouseOfficer.getIdType())
            .setMobile(baseHouseOfficer.getMobile())
            .setName(baseHouseOfficer.getName())
            .setTel(baseHouseOfficer.getTel());
    }

    private List<IpSegInfo> uploadIpSegInfo(BaseHouseInfo baseHouseInfo) {
        return baseIpAddressInfoService.selectList(
            new BaseIpAddressInfo()
                .setHouseId(baseHouseInfo.getId())
        )
            .stream()
            .filter(Objects::nonNull)
            .map(baseIpAddressInfo ->
                new IpSegInfo()
                    .setId(baseIpAddressInfo.getId())
                    .setStartIp(baseIpAddressInfo.getStartIp())
                    .setEndIp(baseIpAddressInfo.getEndIp())
                    .setType(baseIpAddressInfo.getUseType())
                    .setUser(baseIpAddressInfo.getUseCompany())
                    .setIdType(baseIpAddressInfo.getIdType())
                    .setIdNumber(baseIpAddressInfo.getIdNumber())
                    .setSourceUnit(baseIpAddressInfo.getSourceCompany())
                    .setAllocationUnit(baseIpAddressInfo.getAssignCompany())
                    .setUseTime(baseIpAddressInfo.getAssignUseTime())
            ).collect(Collectors.toList());
    }

    private List<GatewayInfo> uploadGatewayInfo(BaseHouseInfo baseHouseInfo) {

        return baseHouseLinkInfoService.selectList(
            new BaseHouseLinkInfo()
                .setHouseId(baseHouseInfo.getId())
        )
            .stream()
            .filter(Objects::nonNull)
            .map(baseHouseLinkInfo ->
                new GatewayInfo()
                    .setAccessUnit(baseHouseLinkInfo.getAccessUnit())
                    .setBandWidth(baseHouseLinkInfo.getBandWidth())
                    .setGatewayIp(baseHouseLinkInfo.getGatewayIp())
                    .setId(baseHouseLinkInfo.getId())
                    .setLinkType(baseHouseLinkInfo.getLinkType())
            ).collect(Collectors.toList());
    }

    /**
     * 上报的机房实体
     *
     * @return
     */
    private HouseInfo uploadHouseInfo(BaseHouseInfo baseHouseInfo) {
        return new HouseInfo()
            .setHouseId(baseHouseInfo.getId())
            .setHouseName(baseHouseInfo.getHouseName())
            .setHouseType(baseHouseInfo.getHouseType())
            .setHouseProvince(baseHouseInfo.getHouseProvince())
            .setHouseCity(baseHouseInfo.getHouseCity())
            .setHouseCounty(baseHouseInfo.getHouseCounty())
            .setHouseAdd(baseHouseInfo.getHouseAddress())
            .setHouseZip(baseHouseInfo.getZipCode());
    }

    private QueryResult defaultQueryResult(IdcInfoManage idcInfoManage, BaseOperCompany baseOperCompany) {
        //安全负责人信息
        BaseHouseOfficer securityOwner = baseHouseOfficerService.selectById(baseOperCompany.getSecurityOwner());
        //应急联系人信息
        BaseHouseOfficer emergencyContact = baseHouseOfficerService.selectById(baseOperCompany.getEmergencyContact());
        return new QueryResult()
            .setCommandId(idcInfoManage.getCommandId())
            .setIdcId(baseOperCompany.getIdcId())
            .setIdcName(baseOperCompany.getOperName())
            .setIdcAdd(baseOperCompany.getAddress())
            .setIdcZip(baseOperCompany.getZipCode())
            .setCorp(baseOperCompany.getCompanyCorporation())
            .setIdcOfficer(toIdcOfficer(securityOwner))
            .setEmergencyContact(toEmergencyContact(emergencyContact));
    }

    /**
     * 转换成安全负责人信息
     *
     * @param baseHouseOfficer
     * @return
     */
    private IdcOfficer toIdcOfficer(BaseHouseOfficer baseHouseOfficer) {
        return new IdcOfficer()
            .setName(baseHouseOfficer.getName())
            .setIdType(baseHouseOfficer.getIdType())
            .setId(baseHouseOfficer.getIdNumber())
            .setTel(baseHouseOfficer.getTel())
            .setMobile(baseHouseOfficer.getMobile())
            .setEmail(baseHouseOfficer.getEmail());
    }

    /**
     * 转换成紧急负责人信息
     *
     * @param baseHouseOfficer
     * @return
     */
    private EmergencyContact toEmergencyContact(BaseHouseOfficer baseHouseOfficer) {
        return new EmergencyContact()
            .setName(baseHouseOfficer.getName())
            .setIdType(baseHouseOfficer.getIdType())
            .setId(baseHouseOfficer.getIdNumber())
            .setTel(baseHouseOfficer.getTel())
            .setMobile(baseHouseOfficer.getMobile())
            .setEmail(baseHouseOfficer.getEmail());
    }


}
